package com.jsh.erp.service.statementaccount;

import com.alibaba.fastjson.JSONObject;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.datasource.entities.StatementAccountExample;
import com.jsh.erp.datasource.entities.Supplier;
import com.jsh.erp.datasource.entities.SupplierExample;
import com.jsh.erp.datasource.entities.User;
import com.jsh.erp.datasource.mappers.StatementAccountEx;
import com.jsh.erp.datasource.mappers.StatementAccountMapper;
import com.jsh.erp.datasource.vo.StatementAccountVo;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.user.UserService;
import com.jsh.erp.utils.BaseResponseInfo;
import com.jsh.erp.utils.ExcelUtils;
import com.jsh.erp.utils.StringUtil;
import jxl.Sheet;
import jxl.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class StatementAccountService {
    private Logger logger = LoggerFactory.getLogger(StatementAccountService.class);

    @Resource
    private StatementAccountMapper statementAccountMapper;

    @Resource
    private StatementAccountEx statementAccountMapperEx;
    @Resource
    private UserService userService;

    public StatementAccountVo getStatementAccountVo(long id)throws Exception {
        StatementAccountVo result=null;
        try{
            result=statementAccountMapper.selectByPrimaryKey(id);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return result;
    }

    public List<StatementAccountVo> getStatementAccountVoListByIds(String ids)throws Exception {
        List<Long> idList = StringUtil.strToLongList(ids);
        List<StatementAccountVo> list = new ArrayList<>();
        try{
            StatementAccountExample example = new StatementAccountExample();
            example.createCriteria().andIdIn(idList);
            list = statementAccountMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list;
    }

    public List<StatementAccountVo> getStatementAccountVo()throws Exception {
        StatementAccountExample example = new StatementAccountExample();
        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<StatementAccountVo> list=null;
        try{
            list=statementAccountMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list;
    }

    public List<StatementAccountVo> select(String statementType,String supplierNumber,  String supplierName,String beginTime, String endTime, int offset, int rows) throws Exception{
        List<StatementAccountVo> resList = new ArrayList<StatementAccountVo>();
        try{
            resList = statementAccountMapperEx.selectByConditionStatementAccount(statementType,supplierNumber,supplierName, beginTime, endTime, offset, rows);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return resList;
    }

    public Long countStatementAccountVo(String statementType,String supplierNumber,  String supplierName,String beginTime, String endTime)  throws Exception{
        Long result=null;
        try{
            result=statementAccountMapperEx.countsByStatementAccount(statementType,supplierNumber,supplierName, beginTime, endTime);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return result;
    }


    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateStatementAccountVo(JSONObject obj, HttpServletRequest request)throws Exception {
        StatementAccountVo statementAccount = JSONObject.parseObject(obj.toJSONString(), StatementAccountVo.class);
        int result=0;
        try{
            result=statementAccountMapper.updateByPrimaryKeySelective(statementAccount);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteStatementAccountVo(Long id, HttpServletRequest request)throws Exception {
        return batchDeleteStatementAccountVoByIds(id.toString());
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteStatementAccountVo(String ids, HttpServletRequest request) throws Exception{
        return batchDeleteStatementAccountVoByIds(ids);
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteStatementAccountVoByIds(String ids)throws Exception {
        int result=0;
        String [] idArray=ids.split(",");
        User userInfo=userService.getCurrentUser();
        //校验通过执行删除操作
        try{
            result = statementAccountMapperEx.batchDeleteStatementAccountByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }





    public List<StatementAccountVo> findByAll(String statementType,String supplierNumber,  String supplierName,String beginTime, String endTime){
        List<StatementAccountVo> list=null;
        try{
            list = statementAccountMapperEx.findByAll(statementType,supplierNumber,supplierName, beginTime, endTime);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertStatementAccountVo(JSONObject obj, HttpServletRequest request)throws Exception {
        StatementAccountVo vo = JSONObject.parseObject(obj.toJSONString(), StatementAccountVo.class);
        int result=0;
        try{
            result=statementAccountMapper.insertSelective(vo);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }


    public Integer batchInsertStatementAccountVo(List<StatementAccountVo> vos) {

        return statementAccountMapper.batchInsertStatementAccountVo(vos);
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void importExcel(String statementType,MultipartFile file, HttpServletRequest request) throws Exception{
        User userInfo = userService.getCurrentUser();
        Workbook workbook = Workbook.getWorkbook(file.getInputStream());
        Sheet src = workbook.getSheet(0);
        List<StatementAccountVo> vos = new ArrayList<>();

        for (int i = 2; i < src.getRows(); i++) {
            StatementAccountVo vo = new StatementAccountVo();
            vo.setStatementType(statementType);
            vo.setStatisticalType("手动导入");
            vo.setFactory(ExcelUtils.getContent(src, i, 1));
            vo.setSupplierNumber(ExcelUtils.getContent(src, i, 2));
            vo.setSupplierName(ExcelUtils.getContent(src, i, 3));
            vo.setDepotNumber(ExcelUtils.getContent(src, i, 4));
            vo.setLineProject(ExcelUtils.getContent(src, i, 5));
            vo.setBarCode(ExcelUtils.getContent(src, i, 6));
            vo.setMaterials(ExcelUtils.getContent(src, i, 7));
            vo.setFyrRef(ExcelUtils.getContent(src, i, 8));
            vo.setReferenceCertificate(ExcelUtils.getContent(src, i, 9));
            vo.setRfIt(ExcelUtils.getContent(src, i, 10));
            vo.setMaterialCount(new BigDecimal(Objects.requireNonNull(ExcelUtils.getContent(src, i, 11))));
            vo.setInvoiceNum(new BigDecimal(Objects.requireNonNull(ExcelUtils.getContent(src, i, 12))));
            vo.setMaterialUnit(ExcelUtils.getContent(src, i, 13));
            vo.setOperTime(new SimpleDateFormat("yyyy-MM-dd").parse(ExcelUtils.getContent(src, i, 14)));
            vo.setUnitPrice(new BigDecimal(Objects.requireNonNull(ExcelUtils.getContent(src, i, 15))));
            vo.setNeedInvoice(new BigDecimal(Objects.requireNonNull(ExcelUtils.getContent(src, i, 16))));
            vo.setNeedInvoiceTax(new BigDecimal(Objects.requireNonNull(ExcelUtils.getContent(src, i, 17))));
            vo.setCurrencyType(ExcelUtils.getContent(src, i, 18));
            vo.setTenantId(userInfo.getTenantId());
            vos.add(vo);
        }
        if (!vos.isEmpty())statementAccountMapper.batchInsertStatementAccountVo(vos);
    }
    public File exportExcel(List<StatementAccountVo> dataList) throws Exception {
        String[] names = {"工厂","供应商","供应商名称","采购订单",   "行项目","物料","物料描述",
                "FYrRef", "参考凭证", "RfIt",  "入库数量",   "仍要开票数量",  "订单单位", "入库日期",
                "采购组",  "不含税单价(本币)",   "仍要开票的净价值(本币)",   "仍要开票价值（含税）",  "单位"};

        String title = "信息内容";
        List<String[]> objects = dataList.stream().map(x -> {
            String[] objs = new String[names.length];
            objs[0] = x.getFactory();
            objs[1] = x.getSupplierNumber();
            objs[2] = x.getSupplierName();
            objs[3] = x.getDepotNumber();
            objs[4] = x.getLineProject();
            objs[5] = x.getBarCode();
            objs[6] = x.getMaterials();
            objs[7] = x.getFyrRef();
            objs[8] = x.getReferenceCertificate();
            objs[9] = x.getRfIt();
            objs[10] = x.getInvoiceNum().setScale(2, RoundingMode.DOWN).toString();
            objs[11] = x.getMaterialUnit();
            objs[12] =  new SimpleDateFormat("yyyy-MM-dd").format(x.getOperTime());
            objs[13] = x.getOrderPeople();
            objs[14] =  x.getUnitPrice().setScale(2, RoundingMode.DOWN).toString();
            objs[15] =  x.getNeedInvoice().setScale(2, RoundingMode.DOWN).toString();
            objs[16] =  x.getNeedInvoiceTax().setScale(2, RoundingMode.DOWN).toString();
            objs[17] =  x.getCurrencyType();
            return objs;
        }).collect(Collectors.toList());
        return ExcelUtils.exportObjectsOneSheet(title, "*导入时本行内容请勿删除，切记！", names, title, objects);
    }

}
